package com.hadoop.hdfs.stream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import sun.nio.ch.IOUtil;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;


/**
 * 相对那些封装好的方法而言的更底层一些的操作方式
 * 上层那些mapreduce   spark等运算框架，去hdfs中获取数据的时候，就是调的这种底层的api
 */
public class StreamAccess {
    FileSystem fileSystem=null;

    @Before
    public  void init() throws URISyntaxException, IOException, InterruptedException {
        Configuration configuration=new Configuration();
        fileSystem=FileSystem.get(new URI("hdfs://192.168.186.148:9000"),configuration,"hadoop");
    }

    /**
     * 通过流的方式上传
     * @throws IOException
     */
    @Test
    public void streamUpload() throws IOException {
        FSDataOutputStream outputStream = fileSystem.create(new Path("/eat.rar"), true);
        FileInputStream inputStream = new FileInputStream("F:\\eat.rar");
        org.apache.commons.io.IOUtils.copy(inputStream,outputStream);
    }

    @Test
    public void streamDownload() throws IOException {
        //先获取一个文件的输入流----针对hdfs上的
        FSDataInputStream inputStream = fileSystem.open(new Path("/aaa"));
        //再构造一个文件的输出流----针对本地的
        FileOutputStream outputStream = new FileOutputStream("h:/aaa.zip");
        //再将输入流中数据传输到输出流
       IOUtils.copyBytes(inputStream,outputStream,4096);;
    }

    /**
     *  hdfs支持随机定位进行文件读取，而且可以方便地读取指定长度
     * 用于上层分布式运算框架并发处理数据
     */
    @Test
    public void randomAccess() throws IOException {
        FSDataInputStream inputStream=fileSystem.open(new Path("/aaa"));
        inputStream.seek(1024);
        FileOutputStream outputStream=new FileOutputStream("h:/bbb.zip");
        IOUtils.copyBytes(inputStream,outputStream,4096);


    }
}
